package com.servicelayer.project;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.core.protocols.IHibernateParentEnumeratorDelegate;
import com.core.protocols.IKVObject;
import com.core.protocols.IServiceLayerDelegate;
import com.managers.hibernate.ExceptionHandler;
import com.managers.hibernate.SessionFactoryManager;
import com.managers.hibernate.exceptionevent.ExceptionEvent;
import com.model.project.ProjectItem;
import com.model.project.ProjectTask;
import com.servicelayer.base.HibernateServiceLayer;

public class ProjectTasksListLayer
        extends HibernateServiceLayer {



    public Class <? extends IKVObject> entityClass () {

        return ProjectTask.class;
    }



    public void enumerateParentObjectsWithDelegate ( IKVObject kvObject,
                                                     IHibernateParentEnumeratorDelegate delegate ) {

        ProjectTask projectTask = (ProjectTask) kvObject;
        while ( projectTask != null ) {

            delegate.onEnumarateParent(projectTask);

            ProjectTask nextParent = projectTask.getParentTask();

            if ( nextParent == null ) {
                ProjectItem projectItem = projectTask.getParentProject();
                delegate.onEnumarateParent(projectItem);
            }

            projectTask = nextParent;
        }

    }



    /**
     * 
     * 
     * 
     */


    public IKVObject addProjectTask ( IKVObject template,
                                      Integer parentProjectId ) {


        IKVObject result = null;

        /**
         * check 4 template
         */

        if ( template == null ) {
            return result;
        }


        IServiceLayerDelegate delegate = this.getLayerDelegate();


        Session session = SessionFactoryManager.sharedInstance().openSession();
        /**
         * check 4 session
         */
        if ( session == null ) {
            return result;
        }

        ProjectListLayer projectListLayer = new ProjectListLayer();
        ProjectItem projectItem = (ProjectItem) projectListLayer.objectByUNID(parentProjectId, session, null);

        /**
         * check 4 parent item
         */
        if ( projectItem == null ) {
            if ( delegate != null ) {
                delegate.responseResponseItemsList(null, this, new Exception("Project not found"));
            }
            return null;
        }



        /**
         * create entity
         */

        Exception exception = null;
        try {

            result = ProjectTasksListLayer.createEntityWithTemplate(template, null, session);

        } catch ( Exception e ) {
            result = null;
        }


        if ( result == null ) {
            return result;
        }

        /**
         * add to parent list
         */


        Transaction transaction = null;
        try {
            ProjectTask newTask = (ProjectTask) result;

            transaction = session.beginTransaction();
            newTask.setParentProject(projectItem);
            projectItem.getProjectTasks().add(newTask);
            transaction.commit();

        } catch ( Exception e1 ) {
            ExceptionHandler.handleException(e1, new ExceptionEvent(ExceptionEvent.ADDCHILDOBJECT));
            result = null;
        }

        List <IKVObject> list = null;
        if ( result != null ) {
            list = new ArrayList <IKVObject>();
            list.add(result);
        }

        /**
         * send result to delegate
         */

        if ( delegate != null ) {
            delegate.responseResponseItemsList(list, this, exception);
        }



        return result;
    }



    /**
     * 
     * 
     * 
     */


    public IKVObject addTaskTask ( ProjectTask template,
                                   Integer parentTaskId ) {

        IKVObject result = null;

        /**
         * check 4 template
         */

        if ( template == null ) {
            return result;
        }


        IServiceLayerDelegate delegate = this.getLayerDelegate();


        Session session = SessionFactoryManager.sharedInstance().openSession();
        /**
         * check 4 session
         */
        if ( session == null ) {
            return result;
        }

        ProjectTask parentTask = (ProjectTask) this.objectByUNID(parentTaskId, session, null);

        /**
         * check 4 parent item
         */
        if ( parentTask == null ) {
            if ( delegate != null ) {
                delegate.responseResponseItemsList(null, this, new Exception("Project not found"));
            }
            return null;
        }



        /**
         * create entity
         */

        Exception exception = null;
        try {

            result = ProjectTasksListLayer.createEntityWithTemplate(template, null, session);

        } catch ( Exception e ) {
            ExceptionHandler.handleException(e, new ExceptionEvent(ExceptionEvent.ADDCHILDOBJECT));
        }


        if ( result == null ) {
            return null;
        }

        /**
         * add to parent list
         */


        Transaction transaction = null;
        try {
            ProjectTask newTask = (ProjectTask) result;

            transaction = session.beginTransaction();
            newTask.setParentTask(parentTask);
            newTask.setParentProject(parentTask.getParentProject());
            parentTask.getSubTasks().add(newTask);
            transaction.commit();

        } catch ( Exception e1 ) {
            ExceptionHandler.handleException(e1, new ExceptionEvent(ExceptionEvent.ADDCHILDOBJECT));
        }

        List <IKVObject> list = null;
        if ( result != null ) {
            list = new ArrayList <IKVObject>();
            list.add(result);
        }

        /**
         * send result to delegate
         */

        if ( delegate != null ) {
            delegate.responseResponseItemsList(list, this, exception);
        }



        return result;
    }



}
